% -------------------------------------------------------------------------
% MAIN
% -------------------------------------------------------------------------

global EPOCHS;
global FUNCTION;
global ERROR;
global LAYERS;

format long;
constants;

patterns = get_patterns();
weights = matrix_weights();
o = zeros(1,length(patterns));

if FUNCTION == 1
    S = desired_parity(patterns);
else
    S = desired_simetry(patterns);
end

for epoch = 1:EPOCHS
    shuffle_p = shuffle_patterns(patterns, S);
    patterns = shuffle_p(1:N+1,:);
    S = shuffle_p(N+2,:);
    
    for i = 1:length(patterns)
        ret = feed_forward(weights, patterns(:,i), S(i));
        deltas = ret{1};
        h = ret{2};
        delta_weights = back_propagation(weights, deltas, h, patterns(:,i));
        for j = 1:length(LAYERS)
            weights{j} = weights{j} + delta_weights{j};
        end
    end
    
    for i = 1:length(patterns)
        o(i) = eval_pattern(weights, patterns(:,i));
    end
    cost = cost_function(S, o);
    if cost <= ERROR
        disp('Epochs: ');
        disp(epoch);
        break;
    end
    msg = sprintf('Cost: %g', cost);
    disp(msg);
end

if cost <= ERROR
    msg = sprintf('Error reached! Cost: %g', cost);
else
    msg = sprintf('Epochs limit reached! Cost: %g', cost);
end

disp(msg);
for i = 1:length(patterns)
    disp('Pattern: ');
    disp(patterns(:,i)');
    disp('Output: ');
    disp(o(i));
    disp('Desired: ');
    disp(S(i));
end
